/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "nfc_app.h"
#include "NT3H.h"
#include "iot_nfc.h"
#include <cJSON.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HI_IO_FUNC_GPIO_1_I2C1_SCL_6 6
#define I2C_IDX_BAUDRATE (400000)

#define CONST_2 2
#define CONST_3 3
#define CONST_4 4
#define CONST_8 8
#define CONST_9 9
#define CONST_10 10
#define CONST_15 15
#define CONST_16 16
#define CONST_32 32
#define CONST_35 35
#define CONST_48 48
#define CONST_64 64
#define CONST_65 65
#define CONST_96 96
#define CONST_97 97
#define CONST_126 126
#define CONST_512 512

char product[50], wifissid[50], wifipwd[50], deviceid[50], devicepwd[50], nodeid[20];

/**
 * @brief NFC JSON数据中，获取WiFi的ssid和密钥及设备DevicesID和密钥
 *
 * @return uint8_t
 */
uint8_t nfc_get_devived_data(void) {
    uint8_t memary_buf[CONST_16 * CONST_15];
    cJSON *json, *jsonTemp; // *jsonArray,
    uint8_t jsonbuf[CONST_512 * CONST_2] = {0};
    char jsonbuf_string[CONST_512 * CONST_2] = {0};
    uint8_t payload_len = 0;
    uint8_t json_len = 0;

    NT3H1101_Read_Userpages(CONST_15, memary_buf);

    payload_len = memary_buf[CONST_4];
    json_len = payload_len - CONST_3;

    printf("payload_len: %d", payload_len);
    //取出真实的json数据包，往后再偏移3位
    for (uint8_t i = 0; i < json_len; i++) {
        jsonbuf[i] = memary_buf[CONST_9 + i];
    }
    memset(jsonbuf_string, 0x00, sizeof(jsonbuf_string));
    sprintf(jsonbuf_string, "%s", jsonbuf);

    printf("nfc data: %s", jsonbuf_string);
    //解析json数据
    json = cJSON_Parse(jsonbuf_string);
    if (!json) {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
        return -1;
    } else {
        jsonTemp = cJSON_GetObjectItem(json, "product");
        memset(product, 0, sizeof(product));
        snprintf(product, strlen(jsonTemp->valuestring) + 1, "%s", jsonTemp->valuestring);
        jsonTemp = cJSON_GetObjectItem(json, "device_id");
        memset(deviceid, 0, sizeof(deviceid));
        snprintf(deviceid, strlen(jsonTemp->valuestring) + 1, "%s", jsonTemp->valuestring);
        jsonTemp = cJSON_GetObjectItem(json, "secret");
        memset(devicepwd, 0, sizeof(devicepwd));
        snprintf(devicepwd, strlen(jsonTemp->valuestring) + 1, "%s", jsonTemp->valuestring);
        jsonTemp = cJSON_GetObjectItem(json, "ssid");
        memset(wifissid, 0, sizeof(wifissid));
        snprintf(wifissid, strlen(jsonTemp->valuestring) + 1, "%s", jsonTemp->valuestring);
        jsonTemp = cJSON_GetObjectItem(json, "pwd");
        memset(wifipwd, 0, sizeof(wifipwd));
        snprintf(wifipwd, strlen(jsonTemp->valuestring) + 1, "%s", jsonTemp->valuestring);

        cJSON_Delete(json);
        free(json); // isequal
    }
    return 0;
}

char byte2char(uint8_t num) {
    char ch;
    if (num >= CONST_32 && num <= CONST_64) {
        ch = '0' + (num - CONST_48);
    } else if (num >= CONST_65 && num <= CONST_96) {
        ch = 'A' + (num - CONST_65);
    } else if (num >= CONST_97 && num <= CONST_126) {
        ch = 'a' + (num - CONST_97);
    } else {
        ch = '0';
    }
    return ch;
}

/**
 * @brief Get the nfc device data object
 *
 * @return uint8_t
 */
uint8_t get_nfc_device_data(void) {
    uint8_t memary_buf[16 * 15] = {0};
    uint8_t payload_len = 0;
    uint8_t start_index = 0; // 取值开始位置
    uint8_t count = 0;       // 取值数量
    NT3H1101_Read_Userpages(CONST_15, memary_buf);
    // 符号SOH+NUL 和 表示1的正文开始，如果不符合，不进行读取
    if (!(memary_buf[CONST_8] == 1 && memary_buf[CONST_9] == 0 && byte2char(memary_buf[CONST_35 + 1]) == '1')) {
        return -1;
    }
    payload_len = memary_buf[CONST_35]; // 十进制的有效数据总长度
    start_index = CONST_35 + CONST_4;   // 表示长度的位置+4为数据位置
    count = (memary_buf[CONST_35 + CONST_2] - CONST_48) * CONST_10 + (memary_buf[CONST_35 + CONST_3] - CONST_48);

    //   03 9B D2 02 96 68 77 20 01 00 48 00 39 41 34 39 00 81 07 00 07 20 06 85 14 91 14 06 00 00 00 00 00 00 91  6B   31 32 34 36 33 31 35 63 39 33 63 36 36 34 63 36 66 37 39 33 38 64 63 32 30 38 37 32 30 38 4C 61 6D 70 5F 30 30 32 33 32 36 31 32 33 34 35 36 41 42 43 44 45 46 47 31 32 33 34 35 36 41 42 43 44 45 46 47 34 30 31 31 35 31 30 74 65 61 6D 58 2D 4C 61 6D 70 36 32 30 56 56 56 56 56 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 8B 0C 12 51 C2 6D 52 32 84 34 A1 82 65 9C FE
    //   124 6315c93c664c6f7938dc2087 208 Lamp_002 326 123456ABCDEFG123456ABCDEFG 401 1 510 teamX-Lamp 620 VVVVVXXXXXXXXXXXXXXX
    //   product_id+_+node_id,pwd

    for (int i = 0; i < count; i++) {
        product[i] = byte2char(memary_buf[start_index + i]);
    }
    printf("product_id=%s\n", product);
    // 下一个起始位置和长度
    start_index += count + CONST_3;
    count = (memary_buf[start_index - CONST_2] - CONST_48) * CONST_10 + (memary_buf[start_index - 1] - CONST_48);
    for (int i = 0; i < count; i++) {
        nodeid[i] = byte2char(memary_buf[start_index + i]);
    }
    printf("node_id=%s\n", nodeid);
    // 下一个起始位置和长度
    start_index += count + CONST_3;
    count = (memary_buf[start_index - CONST_2] - CONST_48) * CONST_10 + (memary_buf[start_index - 1] - CONST_48);
    for (int i = 0; i < count; i++) {
        devicepwd[i] = byte2char(memary_buf[start_index + i]);
    }

    sprintf(deviceid, "%s_%s", product, nodeid);

    printf("device_id=%s,secret=%s\n", deviceid, devicepwd);

    return 0;
}
int BOARD_InitNfc(void) {
    // GPIO_1复用为I2C1_SCL
    IoTGpioSetFunc(1, HI_IO_FUNC_GPIO_1_I2C1_SCL_6);
    // baudrate: 400kbps
    IoTI2cInit(1, I2C_IDX_BAUDRATE);
    return 0;
}

int BOARD_GetNfcInfo(NfcInfo *info) {
    int ret = -1;
    if (info == NULL) {
        return ret;
    }

    if (nfc_get_devived_data() == 0) {
        info->deviceID = (const char *)deviceid;
        info->devicePWD = (const char *)devicepwd;
        info->wifiSSID = (const char *)wifissid;
        info->wifiPWD = (const char *)wifipwd;
        ret = 0;
    } else if (get_nfc_device_data() == 0) {
        info->deviceID = (const char *)deviceid;
        info->devicePWD = (const char *)devicepwd;
        ret = 0;
    }
    return ret;
}
